package com.hengx.cellview.cell;

import static com.hengx.cellview.util.GravityUtils.*;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextPaint;
import android.view.Gravity;
import android.view.MotionEvent;

import com.hengx.cellview.CellView;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class EditTextCell extends TextCell {
    
    private StringBuilder text;
    private boolean displayCursor;
    private int cursorPosition;
    private int cursorColor;
    private float cursorWidth;
    private Editable editable;

    public EditTextCell(String text) {
        super(text);
        init();
    }

    public EditTextCell(String text, int textColor) {
        super(text, textColor);
        init();
    }

    public EditTextCell(String text, int textColor, int backgroundColor) {
        super(text, textColor, backgroundColor);
        init();
    }

    public EditTextCell(String text, int textColor, int backgroundColor, float textSize) {
        super(text, textColor, backgroundColor, textSize);
        init();
    }
    
    private void init() {
    	this.text = new StringBuilder(super.getText());
        this.cursorPosition = text.length();
        this.cursorColor = 0xff2f64ca;
        this.cursorWidth = 3f;
        this.editable = createEditable();
    }

    @Override
    public synchronized void draw(Paint paint, Canvas canvas) {
        super.draw(paint, canvas);
        RectF bounds = getBounds();
        canvas.save();
        canvas.clipRect(bounds);
        if (displayCursor) {
            String[] lines = getLines();
            float lineHeight = getTextSize() + (getVerticalSpacing() * 2f);
            if (lines.length == 0) {
                float cx = bounds.centerX();
                if (containsLeft(getGravity())) {
                    cx = bounds.left;
                } else if (containsRight(getGravity())) {
                    cx = bounds.right - cursorWidth;
                }
                paint.setStyle(Paint.Style.FILL);
                paint.setColor(0xff0067ff);
                canvas.drawRect(cx, bounds.top + ((bounds.height() / 2f) - (lineHeight / 2f)), cx + cursorWidth, bounds.top + ((bounds.height() / 2f) - (lineHeight / 2f)) + lineHeight, paint);
            }else{
                float baseX = bounds.left;
                float baseY = bounds.top;
                float maxHeight = lineHeight * lines.length;
                if (containsBottom(getGravity())) {
                    baseY = Math.max(bounds.top, bounds.bottom - maxHeight);
                } else if (containsCenterVertical(getGravity())) {
                    baseY = Math.max(bounds.top, bounds.top + (bounds.height() / 2f) - (maxHeight / 2f));
                }
                float ascent = Math.abs(paint.ascent());
                int currentPosition = 0;
                for(int i = 0; i < lines.length; i++) {
                    float lineY = baseY + (i * lineHeight);
                    if (lineY > bounds.bottom) break;
                    String line = lines[i];
                    float lineX;
                    if (containsLeft(getGravity())) {
                        lineX = baseX;
                    } else if (containsRight(getGravity())) {
                        lineX = Math.max(baseX, baseX + bounds.width() - paint.measureText(line));
                    } else {
                        lineX = Math.max(baseX, baseX + (bounds.width() / 2f) - (paint.measureText(line) / 2f));
                    }
                    float cx = lineX;
                    for(int i2 = 0; i2 < line.length(); i2++) {
                        String c = String.valueOf(line.charAt(i2));
                        float cw = paint.measureText(c);
                        if (cursorPosition == currentPosition) {
                            //在前面绘制光标
                            paint.setStyle(Paint.Style.FILL);
                            paint.setColor(cursorColor);
                            canvas.drawRect(cx, lineY, cx + cursorWidth, lineY + lineHeight, paint);
                        } else if (i2 == line.length() - 1 && cursorPosition == currentPosition + 1) {
                            //在最后绘制光标
                            paint.setStyle(Paint.Style.FILL);
                            paint.setColor(cursorColor);
                            canvas.drawRect(cx + cw, lineY, cx + cw + cursorWidth, lineY + lineHeight, paint);
                        }
                        currentPosition++;
                        cx += cw;
                    }
                    /*if (line.endsWith("\n")) currentPosition++;
                    currentPosition++;*/
                }
            }
        }
        canvas.restore();
    }
    
    @Override
    public String getText() {
        return text.toString();
    }
    
    @Override
    public void setText(String text) {
        super.setText(text);
        this.text = new StringBuilder(text);
        this.cursorPosition = text.length();
    }
    
    public EditTextListener startEditText(CellView view) {
    	return new EditTextListener() {
            @Override
            public void displayCursor(boolean displayCursor) {
                EditTextCell.this.displayCursor = displayCursor;
                view.invalidate();
            }
            @Override
            public void append(String content) {
                text.insert(cursorPosition, content);
                cursorPosition += content.length();
                EditTextCell.super.setText(text.toString());
                view.invalidate();
            }
            @Override
            public void delete() {
                if (cursorPosition > 0) {
                    text.deleteCharAt(cursorPosition - 1);
                    cursorPosition--;
                    EditTextCell.super.setText(text.toString());
                    view.invalidate();
                }
            }
            @Override
            public void onClick(float x, float y) {
                
            }
            @Override
            public void end() {
                displayCursor = false;
                view.invalidate();
            }
            @Override
            public void moveCursorBottom() {
            }
            
            @Override
            public void moveCursorTop() {
                
            }
            @Override
            public void moveCursorRight() {
                if (cursorPosition < text.length()) cursorPosition++;
                view.invalidate();
            }
            @Override
            public void moveCursorLeft() {
                if (cursorPosition > 0) cursorPosition--;
                view.invalidate();
            }
        };
    }
    
    public interface EditTextListener {
        void displayCursor(boolean displayCursor);
        void append(String content);
        void delete();
        void onClick(float x, float y);
        void end();
        void moveCursorLeft();
        void moveCursorTop();
        void moveCursorRight();
        void moveCursorBottom();
    }
    
    public boolean getDisplayCursor() {
        return this.displayCursor;
    }

    public void setDisplayCursor(boolean displayCursor) {
        this.displayCursor = displayCursor;
    }
    
    public int getCursorPosition() {
    	return this.cursorPosition;
    }
    
    public void setCursorPosition(int cursorPosition) {
    	this.cursorPosition = cursorPosition;
    }

    public int getCursorColor() {
        return this.cursorColor;
    }

    public void setCursorColor(int cursorColor) {
        this.cursorColor = cursorColor;
    }

    public float getCursorWidth() {
        return this.cursorWidth;
    }
    
    public void setCursorWidth(float cursorWidth) {
        this.cursorWidth = cursorWidth;
    }
    
    public Editable getEditable() {
    	return this.editable;
    }
    
    
    private Editable createEditable() {
    	return new Editable() {
            @Override
            public android.text.Editable append(CharSequence arg0) {
                text.append(arg0);
                return this;
            }

            @Override
            public android.text.Editable append(CharSequence arg0, int arg1, int arg2) {
                text.append(arg0, arg1, arg2);
                return this;
            }

            @Override
            public android.text.Editable append(char arg0) {
                text.append(arg0);
                return this;
            }

            @Override
            public char charAt(int arg0) {
                return text.charAt(arg0);
            }

            @Override
            public java.util.stream.IntStream chars() {
                return text.chars();
            }

            @Override
            public void clearSpans() {
            }

            @Override
            public android.text.Editable delete(int arg0, int arg1) {
                text.delete(arg0, arg1);
                cursorPosition = Math.min(cursorPosition, text.length());
                return this;
            }

            @Override
            public void clear() {
                text.setLength(0);
                cursorPosition = 0;
            }

            @Override
            public java.util.stream.IntStream codePoints() {
                return text.codePoints();
            }

            @Override
            public android.text.InputFilter[] getFilters() {
                return null;
            }

            @Override
            public int getSpanEnd(Object arg0) {
                return 0;
            }

            @Override
            public int getSpanStart(Object arg0) {
                return 0;
            }

            @Override
            public android.text.Editable insert(int arg0, CharSequence arg1, int arg2, int arg3) {
                text.insert(arg0, arg1, arg2, arg3);
                return this;
            }

            @Override
            public void getChars(int arg0, int arg1, char[] arg2, int arg3) {
                text.getChars(arg0, arg1, arg2, arg3);
            }

            @Override
            public int getSpanFlags(Object arg0) {
                return 0;
            }

            @Override
            public <T extends java.lang.Object> T[] getSpans(int arg0, int arg1, Class<T> arg2) {
                return null;
            }

            @Override
            public android.text.Editable insert(int arg0, CharSequence arg1) {
                text.insert(arg0, arg1);
                return this;
            }

            @Override
            public int length() {
                return text.length();
            }

            @Override
            public void removeSpan(Object arg0) {
            }

            @Override
            public int nextSpanTransition(int arg0, int arg1, Class arg2) {
                return 0;
            }

            @Override
            public android.text.Editable replace(int arg0, int arg1, CharSequence arg2, int arg3, int arg4) {
                return this;
            }

            @Override
            public android.text.Editable replace(int arg0, int arg1, CharSequence arg2) {
                text.replace(arg0, arg1, arg2.toString());
                return this;
            }

            @Override
            public void setSpan(Object arg0, int arg1, int arg2, int arg3) {
            }

            @Override
            public java.lang.CharSequence subSequence(int arg0, int arg1) {
                return text.subSequence(arg0, arg1);
            }

            @Override
            public void setFilters(InputFilter[] arg0) {
            }
        };
    }

}